package context;

import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Form;
import javax.microedition.lcdui.TextBox;
import javax.microedition.lcdui.TextField;

// ********************************************************************
// *** CLASS: Debug
// ********************************************************************
/**
 * <pre>
 * Typical usage:
 *
 * 1) To show the debug text screen:
 *       Debug.show(display);
 *
 * 2) Anywhere:
 *       Debug.println(" any text ");
 * </pre>
 */
public class Debug
{ 
  
	  public interface Constants
	  { static final boolean DEBUG=true; //false;
	    static final boolean LOG_XML=true;//false;
	    static final boolean LOG_PLAY_EVENT=true;
	    static final boolean LOG_CONNECTION_OPEN=true;
	    static final boolean LOG_MAIN_EVENTS=true;
	  }
  
  private static final DebugScreen1 debug=new DebugScreen1();
  private static final DebugScreen2 debug2=new DebugScreen2();
  
  public static Boolean lock=new Boolean(false); // To synchronize print
  public static String IDENT="";
  private static String threadID(){return(Thread.currentThread().getName());}
  
  public static void log(String who,String msg) { println(" LOG: "+msg); }
  public static void ERROR(String s) { ERROR("ERROR",s,null); }
//  public static void EXCEPTION(String s,Exception e) { ERROR("EXCEPTION",s+""+e.getMessage(),e); }
  public static void EXCEPTION(String s,Throwable e) { ERROR("EXCEPTION",e.toString()+": "+s,e); }
  public static void NOT_IMPLEMENTED(String s) { println("*** NOT IMPLEMENTED: "+s); }
  
  public static void ASSERT(boolean test,String msg)
  { if(!test)
    { synchronized(lock)
      { try { throw new RuntimeException("ASSERT("+msg+") -- FAILED"); }
        catch(Exception e) { e.printStackTrace(); }
      }
      //ERROR("ASSERTION FAILED",msg,null);
    }
  }

  public static void ERROR(String title,String s,Throwable e)
  { synchronized(lock)
	{ String msg="*** "+title+": "+s;
      println(msg);
      if(e!=null) e.printStackTrace();
      Context.showError(msg);
    }
  }

  public static void println(String s)
  { synchronized(lock)
      { try
        { s=s.replace('\r',(char)0);
          s=s.replace('\n',(char)0);
          System.out.println(IDENT+s);
          if(debug!=null) debug.println(IDENT+s);
//          if(Context.TRACING)
//        	  Context.trace(s);
        }
        catch(Exception e)
        { System.out.println("*** EXCEPTION while printing debug info: "+e); }
      }
    }


  
  
//  public static void show(Display display) { if(debug!=null) debug.show(display); }
  public static void show() { if(debug!=null) debug.show(); }

  // ******************************************************************
  // *** INNER CLASS: DebugScreen
  // ******************************************************************
  private static class DebugScreen1 extends TextBox
  { private static final Command backCommand=new Command("Back",Command.SCREEN,2);
    private static final Command clearCommand=new Command("Clear Debug",Command.SCREEN,1);
    private Displayable prev;
    
    // ****************************************************************
    // *** CONSTRUCTOR: DebugScreen
    // ****************************************************************
    public DebugScreen1()
    { super("Debug Info",null,4096,TextField.ANY);
      this.addCommand(clearCommand);
      this.addCommand(backCommand);
      setCommandListener(new CommandListener()
      { public void commandAction(Command c,Displayable s)
        { if(c==clearCommand) clear();
          else if(c==backCommand) Context.setCurrent(prev);
        }
      });
    }
    
    // ****************************************************************
    // *** METHOD: show
    // ****************************************************************
    public void show()
    { prev=Context.setCurrent(this); }

    // ****************************************************************
    // *** METHOD: println
    // ****************************************************************
    public void println(String s)
    { try
      { this.insert(s,this.getCaretPosition());
        this.insert(" \r\n",this.getCaretPosition());
      } catch(IllegalArgumentException e) { clear(); }
    }

    /*
     * Clear Debug Info
     */
    public void clear() { if(size()>0) delete(0,size()); }
    
  }
  
  
  
  // ******************************************************************
  // *** INNER CLASS: DebugScreen
  // ******************************************************************
  private static class DebugScreen2 extends Form
  { private static final Command backCommand=new Command("Back",Command.SCREEN,2);
    private static final Command clearCommand=new Command("Clear Debug",Command.SCREEN,1);
	private Displayable prev;
    private TextField trace;
    
    // ****************************************************************
    // *** METHOD: show
    // ****************************************************************
    public void show()
    { prev=Context.setCurrent(this); }
    
    public DebugScreen2()
    { super("");
      trace=new TextField("Trace","",5000,TextField.ANY|TextField.UNEDITABLE);
      append(trace);
      this.addCommand(backCommand);
      this.addCommand(clearCommand);
      
      this.setCommandListener(new CommandListener()
      { public void commandAction(Command c,Displayable s)
        { if(c==clearCommand) clear();
          else if(c==backCommand) Context.setCurrent(prev);
        }
      });
    }
    
    public void clear() { trace.setString(""); }
    
    // ****************************************************************
    // *** METHOD: println
    // ****************************************************************
    public void println(String line) { trace.insert(line+'\n',0); }

  }

  
}
